<?php
/**
*  @package :  class.main
*  @classID :   router.class.php
*  @author  :  邝达峰
*  @date    : 2017.07.15
*  网站路由处理类
*/

class Router
{
	/**
    * 构造函数
    * @param:  NULL
    * @return: NULL
    * @access: public
    */
	public function __construct(){
		#非法链接处理
		self::illegalityUrlHandle();
	}

	/**
     * 非法链接处理
     * @author 邝达峰
     **/
	public function illegalityUrlHandle()
	{
		$arrNotAllowExtension = array('htm','asp','aspx','jsp','xhtml','rar','zip','tar','gz');
		$strMatchUrl = $_SERVER['PHP_SELF']?$_SERVER['PHP_SELF']:$_SERVER['REQUEST_URI'];
		$arrUrlParseInfo = parse_url($strMatchUrl);
		if(is_array($arrUrlParseInfo))
		{
			$arrUrlPathInfo = pathinfo($arrUrlParseInfo['path']);
			$strUrlExtension = $arrUrlPathInfo['extension'];
			if(in_array($strUrlExtension,$arrNotAllowExtension)){
				#跳转404页面
				goTo404();
			}
		}
	}

	/**
    * 析构函数
    * @param:  NULL
    * @return: NULL
    * @access: public
    */
	public function __destruct(){}

	/**
	 * 路由重写地址处理
	 * @param array $arrUrls 需要处理
	 */
	public function url_rewrite_handle($arrUrls = array()){
		$requestUrl = $_SERVER['REQUEST_URI'];
		$strRequestHost = $_SERVER['HTTP_HOST'];//来访域名
		if(is_array($arrUrls) && count($arrUrls) > 0){
			foreach ($arrUrls as $k=>$v){
				if(!empty($k) && !empty($v)){
					$arrParseUrl = parse_url($k);
					$strMatchHost = $arrParseUrl['host']?$arrParseUrl['host']:$strRequestHost;
					$strMatchUrl = $arrParseUrl['path']?$arrParseUrl['path']:$requestUrl;
					$strPregUrl = '{'.trim($strMatchUrl,'/').'}';#匹配地址
					$strRouteUrl = $k;#路由地址
					$strModule = $v;#执行模块
					if($strRequestHost==$strMatchHost){
						if(empty($arrParseUrl['path']) && $requestUrl!=='/'){
							$strModule = $this->handle_default_module();#处理默认路由模块
						}
						else if($strRouteUrl==$requestUrl){
							$this->match_app_module($strModule);
							break;
						}
						else if(preg_match($strPregUrl, $requestUrl, $arrMatches)){
							$this->match_app_module($strModule,$arrMatches);
							break;
						}
					}
				}
			}//end foreach
			$this->handle_router_params();//处理路由参数
		}
	}

	/**
	 * 处理默认路由模块
	 */
	public function handle_default_module()
	{
		$strHandleModule = '';
		$strModule= $_GET[MODULE_NAME];
		if(!empty($strModule)){
			$strAction= $_GET[CONTROLLER_NAME]?$_GET[CONTROLLER_NAME]:'index';
			$strHandleModule.=$strModule.'.'.$strAction;
			return $strHandleModule;
		}
		return null;
	}

	/**
	 * 匹配应用模块
	 * @param array $strMatch 匹配参数
	 * @param array $arrParams 正规匹配参数
	 */
	public function match_app_module($strMatch='',$arrParams=array()){
		if(!empty($strMatch)){
			$arrModule = explode('.',$strMatch);
			list($module, $controller, $function) = $arrModule;
			$_REQUEST[MODULE_NAME] = $_GET[MODULE_NAME] = $module = $module ? $module : MODULE_DEFAULT_NAME;
			$_REQUEST[CONTROLLER_NAME] = $_GET[CONTROLLER_NAME] = $controller = $controller ? $controller : CONTROLLER_DEFAULT_NAME;
			$_REQUEST[FUNCTION_NAME] = $_GET[FUNCTION_NAME] = $function = $function ? $function : FUNCTION_DEFAULT_NAME;
			#匹配对应的参数
			if(is_array($arrParams) && count($arrParams) > 0){
				if(count($arrModule) > 3){
					$arrMatchParams = array_slice($arrModule,3);
					if(is_array($arrMatchParams) && is_array($arrParams) && count($arrParams)>1){
						$arrParams = array_slice($arrParams,1);
						foreach ($arrMatchParams as $k=>$v){
							$_REQUEST[$v] = $_GET[$v] = $arrParams[$k];
						}
					}
				}
			}
		}
	}

	/**
	 * 处理路由自定义参数值
	 */
	private function handle_router_params()
	{
		if(!empty($_GET['params'])){
			if(strpos($_GET['params'], '-') !== false){
				$arrParams = explode('-',trim($_GET['params'],'-'));
				if(is_array($arrParams)){
					$countParams = count($arrParams);
					if($countParams==3){
						array_shift($arrParams);
					}
					$num = 1;
					foreach ($arrParams as $k=>$v){
						if($num%2===0){
							$_GET[$arrParams[$num-2]] = $arrParams[$num-1];
						}
						$num+=1;
					}
				}
			}
		}
	}

	/**
	 * 地址301跳转
	 * @param array $arrUrls 需要处理
	 */
	public function url_301_skip($arrUrls = array()){
		$requestHost = $_SERVER['HTTP_HOST'];#服务器访问域名
		$requestUrl = $_SERVER['REQUEST_URI'];//服务器访问地址
		$strSkipUrl = WWW_SITE_ROOT.$requestUrl;//默认跳转地址
		$strRegexHost = WWW_SITE_ROOT;//匹配域名
		#处理跳转
		if(is_array($arrUrls) && count($arrUrls) > 0){
			foreach ($arrUrls as $k=>$v){
				if(!empty($k) && !empty($v)){
					$strRouteUrl = $k;//路由地址
					$arrUrlPath = $this->url_parse($k);//解析跳转原地址
					if(is_array($arrUrlPath)){
						$strRegexHost = $arrUrlPath['host'];
						$strRouteUrl = $arrUrlPath['path'];
					}
					$arrUrlSkipPath = $this->url_parse($v);//解析跳转后地址
					if(is_array($arrUrlSkipPath)){
						$strSkipHost = $arrUrlSkipPath['host'];
						$strSkipUrlPath  = $arrUrlSkipPath['path'];
					}
					$strPregUrl = '{'.$strRouteUrl.'}';#匹配地址
					#地址跳转处理
					if($strRegexHost==$requestHost){
						if($strRouteUrl==$requestUrl){
							$strSkipUrl = 'http://'.$strSkipHost.$strSkipUrlPath;
							$this->goto_301($strSkipUrl);
						}
						else {
							if(preg_match($strPregUrl, $requestUrl, $arrMatches)){
								$strSkipUrl = $this->match_skip_url_params($v,$arrMatches);
								$this->goto_301($strSkipUrl);
							}
						}
					}
				}
			}
		}
	}

	/**
	 * 地址解析
	 * @param array $strUrl 需要处理地址
	 */
	public function url_parse($strUrl){
		if(!empty($strUrl)){
			$arrUrlPath = parse_url($strUrl);//解析地址
			$strHost  = WWW_SITE_ROOT;
			$strUrl =  $_SERVER['REQUEST_URI'];
			$arrParseUrl = array();
			if(is_array($arrUrlPath)){
				if(!empty($arrUrlPath['host'])){
					$strHost = $arrUrlPath['host'];
				}
				if(!empty($arrUrlPath['path'])){
					$strUrl = $arrUrlPath['path'];
				}
			}
			$arrParseUrl['host'] = str_replace('http://','',$strHost);
			$arrParseUrl['path'] = $strUrl;
			return $arrParseUrl;
		}
	}

	/**
	 * 地址301跳转
	 * @param array $strSkipUrl 需要处理地址
	 */
	public function goto_301($strSkipUrl){
		if(!empty($strSkipUrl)){
			#地址301跳转
			header("HTTP/1.1 301 Moved Permanently");
			header("Location: $strSkipUrl");
			exit;
		}
	}

	/**
	 * 地址跳转参数匹配
	 * @param array $strUrl 需要处理的地址
	 * @param array $arrParams 需要处理的参数
	 */
	public function match_skip_url_params($strUrl='',$arrParams=array()){
		if(!empty($arrParams) && !empty($strUrl)){
			if(is_array($arrParams) && count($arrParams)>1){
				$matchUrl = $strUrl;
				$arrParams = array_slice($arrParams,1);
				$intNum = 0;
				foreach ($arrParams as $k=>$v){
					$intNum = (int)($k+1);
					$matchUrl = str_replace('$'.$intNum,$v,$matchUrl);
				}
			}
			return $matchUrl;
		}
	}

	/**
	* 参数过滤与防攻击处理
	*/
	public function injectParamFilter()
{
    #过滤 $_POST
    if($_POST){
        $postfilter="^\\+\/v(8|9)|\\b(and|or)\\b.{1,6}?(=|>|<|\\bin\\b|\\blike\\b)|\\/\\*.+?\\*\\/|<\\s*script\\b|\\bSLEEP\\b\(|\\bEXEC\\b\(|UNION.+?SELECT|UPDATE.+?SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE|FUNCTION)";
        foreach ($_POST as $kp=>$vp)
        {
            if(is_string($vp))
            {
            	$vg = urldecode($vp);
                $_POST[$kp]=$this->stringParamFilter($vp);
                $_POST[$kp]=$this->preventParamAttack($vp,$postfilter);#防攻击处理
            }
        }
    }
    #过滤 $_GET
    if($_GET){
        $getfilter="'|<[^>]*?>|^\\+\/v(8|9)|\\b(and|or)\\b.+?(>|<|=|\\bin\\b|\\blike\\b)|\\/\\*.+?\\*\\/|<\\s*script\\b|\\bSLEEP\\b\(|\\bEXEC\\b\(|UNION.+?SELECT|UPDATE.+?SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE|FUNCTION)";
        foreach ($_GET as $kg=>$vg)
        {
            if(is_string($vg))
            {
            	$vg = urldecode($vg);
                $_GET[$kg]=$this->stringParamFilter($vg);
                $_GET[$kg]=$this->preventParamAttack($vg,$getfilter);#防攻击处理
            }
        }
    }
    #过滤 $_REQUEST
    if($_REQUEST){
        foreach ($_REQUEST as $kr=>$vr)
        {
            if(is_string($vr))
            {
                $_REQUEST[$kr]=$this->stringParamFilter($vr);
            }
        }
    }
    #过滤 $_COOKIE
    if($_COOKIE){
        $cookiefilter="\\b(and|or)\\b.{1,6}?(=|>|<|\\bin\\b|\\blike\\b)|\\/\\*.+?\\*\\/|<\\s*script\\b|\\bSLEEP\\b\(|\\bEXEC\\b\(|UNION.+?SELECT|UPDATE.+?SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE|FUNCTION)";
        foreach($_COOKIE as $kc=>$vc){
            $_COOKIE[$kc]=$this->preventParamAttack($vc,$cookiefilter);#防攻击处理
        }
    }
}

	/**
	 * 字符过滤与防攻击处理
	 * @param string $str
	 * @return string
	 */
	public function stringParamFilter($str)
	{
		if(!empty($str)){
			//使用反斜线引用字符串
			if (!get_magic_quotes_gpc()){
				if (function_exists('addslashes')){
					$str = addslashes($str);
				}
			}
			#'_'过滤掉
			$str = str_replace("_", "\_", $str);
			#'%'过滤掉
			$str = str_replace("%", "\%", $str);
			//$str = nl2br($str);#回车转换
		}
		return $str;
	}

	/**
      * 防攻击处理
      * @param $string $strFiltValue
      * @param $string $arrFiltReq
    */
	public function preventParamAttack($strFiltValue,$arrFiltReq){
		if(isset($strFiltValue) && !empty($arrFiltReq))
		{
			if (preg_match("/".$arrFiltReq."/is",$strFiltValue)==1){
				$strFiltValue = preg_replace("/".$arrFiltReq."/is", '${0}<!--filter_illegality_params-->', $strFiltValue);
				return ''.$strFiltValue.'';
			}else
			{
				return $strFiltValue;
			}
		}
	}


}
?>